package me.huha.zhime.controller;

import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.huha.ibatis.sqlbuilder.SpecificationBuilder;
import me.huha.tools.DateUtils;
import me.huha.zhime.commons.OrderInfoDTO.PayType;
import me.huha.zhime.entity.OrderInfoEntity;
import me.huha.zhime.entity.OrderInfoEntity.PaymentStatusEnum;
import me.huha.zhime.entity.OrderInfoEntity_;
import me.huha.zhime.pay.util.WeChatUtil;
import me.huha.zhime.service.WechatPayService;
import me.huha.zhime.utils.DoubleUtils;
import me.huha.zhime.utils.QRCodeUtil;
import me.huha.zhime.utils.Util;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alipay.api.AlipayApiException;
import com.google.gson.JsonObject;

/**
 * @Title: WeChatPayController
 * @Author: Yepx
 * @mail: yepx2013@gmail.com
 * @CreateTime: 2017年10月25日 下午2:13:48
 * @Todo: 微信支付相应的回调
 */
@Controller
@RequestMapping("weChat")
public class WeChatPayController {
	
	private static Logger logger = Logger.getLogger(WeChatPayController.class);

	@Autowired
	private WechatPayService wechatPayService;
	
	/**
	 * 微信预支付
	 * 
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws AlipayApiException
	 */
	@RequestMapping(value = "/pay")
	public ModelAndView pay() throws UnsupportedEncodingException,
			AlipayApiException {

		String result = "";
		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = Util.getUUID();
		// 付款金额，必填，单位分
		String total_fee = "1";
		// 订单名称，必填
		String body = "测试产品";
		// 商品描述，可空
		String detail = "不可描述的产品";
		// 终端IP,APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
		String spbill_create_ip = "192.168.1.178";
		
		OrderInfoEntity entity = new OrderInfoEntity();
		entity.setOrderNum(out_trade_no);
		entity.setGoodName(body);
		
		double amount = DoubleUtils.div(1d, 100d, 2);
		BigDecimal orderAmount = new BigDecimal(amount);
		
		entity.setOrderAmount(orderAmount);
		entity.setPayType(PayType.weixin.toString());
		entity.setPaymentStatus(PaymentStatusEnum.unpaid.getStatus());
		entity.setOrderCreate(new Date());
		entity.setOrderClose(DateUtils.addDays(new Date(), 1));
		entity.createOrUpdate();

		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.put("out_trade_no", out_trade_no);
		parameters.put("spbill_create_ip", spbill_create_ip);
		parameters.put("body", body);
		parameters.put("detail", detail);
		parameters.put("total_fee", total_fee);
		JsonObject jo = WeChatUtil.payPrepay(parameters);
		// createCode
		if ("SUCCESS".equals(jo.get("return_code").getAsString())
				&& "SUCCESS".equals(jo.get("result_code").getAsString())) {
			// 预支付成功
			result = "<img src=" + QRCodeUtil.qRCodeImgAndUpload(jo.get("code_url").getAsString())
					+ "></img>";
		} else {
			// 预支付失败
			result = "操作失败";
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sHtmlText", result);
		ModelAndView model = new ModelAndView("index", map);
		return model;
	}
	
	/**
     * 微信支付交易推送接口
     * @param request
     * @return
     */
    @RequestMapping(value = "/tradePush")
    public String tradePush(HttpServletRequest request, HttpServletResponse response) {
        logger.info("微信支付推送------------微信支付交易推送接口------------");
        // 接受微信的推送数据存放到map
        SortedMap<Object, Object> map = new TreeMap<Object, Object>();
        SAXReader reader = new SAXReader();
        try {
            InputStream ins = request.getInputStream();
            Document document = reader.read(ins);
            Element root = document.getRootElement();
            List<Element> elementList = root.elements();
            for (Element element : elementList) {
                map.put(element.getName(), element.getText());
            }
            ins.close();
        } catch (Exception e) {
            logger.error("", e);
        }
        // 验签
        String checkSign = WeChatUtil.getSign(map);
        if (checkSign.equals((String) map.get("sign"))) {
            String retXml = "";
            // 验签成功，进行业务判断
            logger.info("pc微信支付推送------------微信支付交易推送接口------------验签成功");
            if ("SUCCESS".equals((String) map.get("result_code"))) {
                // 支付成功
                String out_trade_no = (String) map.get("out_trade_no");
                try {
                  
                	 //查询订单
                    OrderInfoEntity orderInfo = OrderInfoEntity.create(OrderInfoEntity.class)
                    										   .findUnique(SpecificationBuilder.builder()
                    										   .where(OrderInfoEntity_.orderNum.eq(out_trade_no)).build(), null);
                    if (orderInfo != null) {
                        if (PaymentStatusEnum.getPaymentStatusEnumByStatus(orderInfo.getPaymentStatus()) == PaymentStatusEnum.unpaid) {
                            // 判断卖家以及金额获取请求时候是否一致
                            String currentDateTime = Util.date2str(8, null);
                            Map<String, String> payStatusMap = new HashMap<String, String>();
                            payStatusMap.put("hasPay", "1");
                            payStatusMap.put("payTime", currentDateTime);
                            payStatusMap.put("payType", "2");// 1-支付宝，2-微信支付

                            // 判断支付金额和实际支付金额是否相等
                            String totalFeeString = (String) map.get("total_fee");
                            BigDecimal orderAmountB = orderInfo.getOrderAmount();
                           
                            Double orderAmount = DoubleUtils.multiply(orderAmountB.doubleValue(), 100d);
                            Integer orderAmountInt = orderAmount.intValue();

                            if (totalFeeString.equals(orderAmountInt.toString())) {
                                // 支付正常
                            	payStatusMap.put("payStatus", "1");
                                
                            } else {
                                // 支付异常
                            	payStatusMap.put("payStatus", "2");
                            }
                            payStatusMap.put("hasPayTotalAmt", totalFeeString);
                            
                            // TODO 插入wechat返回的数据
                            wechatPayService.doTradeCallback(map, payStatusMap, orderInfo);
                           
                            logger.info("微信支付推送，验证成功");
                            retXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                                     + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                            
                            out.write(retXml.getBytes());
                            out.flush();
                            out.close();
                        }
                    } else {
                        logger.info("非本系统的数据");
                    }
                } catch (Exception e) {
                    logger.error("", e);
                }
            } else {
                // 支付失败
                logger.info("支付失败,错误信息：" + map.get("err_code"));

            }
        } else {
            // 验签失败，不作处理
            logger.info("pc微信支付推送------------微信支付交易推送接口(天天优惠交易)------------验签失败");
        }

        return null;
    }
}
